#include "serialthread.h"

#include <QDebug>
#include "cirbuff.h"

SerialThread::SerialThread(QThread *parent)
    : QThread(parent)
{
    m_isExit = false;
    m_serialport= new QSerialPort(this);
    connect(m_serialport,SIGNAL(readyRead()),
            this,SLOT(slotReadyRead()));
}

SerialThread::~SerialThread()
{

}

void SerialThread::run(void)
{
    while(!m_isExit)
    {
        if(gainCompleteMsg())
        {
            parseDevMsg();
        }
        msleep(2);
    }
}

void SerialThread::parseDevMsg(void)
{
    switch(m_protocol.m_device)
    {
    case DEV_Warn: parseWarnDev(); break;
    case DEV_Beep: parseBeepDev(); break;
    case DEV_Mode: parseModeDev(); break;
    case DEV_Temp: parseTempDev(); break;
    case DEV_Humi: parseHumiDev(); break;
    }
}


void SerialThread::parseWarnDev(void)
{
    switch(m_protocol.m_deviceCmd)
    {
    case CMD_WarnData: emit signalWarnInfo(CMD_WarnData); break;
    case CMD_WarnOvrT: emit signalWarnInfo(CMD_WarnOvrT); break;
    case CMD_WarnLowT: emit signalWarnInfo(CMD_WarnLowT); break;
    case CMD_WarnOvrH: emit signalWarnInfo(CMD_WarnOvrH); break;
    case CMD_WarnLowH: emit signalWarnInfo(CMD_WarnLowH); break;
    }
}

void SerialThread::parseBeepDev(void)
{
    switch(m_protocol.m_deviceCmd)
    {
    case CMD_BeepOn: emit signalBeepStatu(true); break;
    case CMD_BeepOff: emit signalBeepStatu(false); break;
    }
}

void SerialThread::parseModeDev(void)
{
    switch(m_protocol.m_deviceCmd)
    {
    case 0: emit signalModeInfo(0); break;
    case 1: emit signalModeInfo(1); break;
    case 2: emit signalModeInfo(2); break;
    }
}

void SerialThread::parseTempDev(void)
{
    switch(m_protocol.m_deviceCmd)
    {
    case CMD_TempReal: emit signalTempValue(CMD_TempReal, QString((char *)m_protocol.m_data)); break;
    case CMD_TempMaxV: emit signalTempValue(CMD_TempMaxV, QString((char *)m_protocol.m_data)); break;
    case CMD_TempMinV: emit signalTempValue(CMD_TempMinV, QString((char *)m_protocol.m_data)); break;
    }
}

void SerialThread::parseHumiDev(void)
{
    switch(m_protocol.m_deviceCmd)
    {
    case CMD_HumiReal: emit signalHumiValue(CMD_HumiReal, QString((char *)m_protocol.m_data)); break;
    case CMD_HumiMaxV: emit signalHumiValue(CMD_HumiMaxV, QString((char *)m_protocol.m_data)); break;
    case CMD_HumiMinV: emit signalHumiValue(CMD_HumiMinV, QString((char *)m_protocol.m_data)); break;
    }
}

bool SerialThread::gainCompleteMsg(void)
{
    m_protocol.clearProtocoldata();
    if(CirBuff::readByte() == BGN_RESD_MSG)
    {
        m_protocol.m_device     = CirBuff::readByte();
        m_protocol.m_deviceCmd     = CirBuff::readByte();
        m_protocol.m_dataLen       = CirBuff::readByte();

        if(m_protocol.m_dataLen > 0)
        {
            m_protocol.m_data = new quint8[m_protocol.m_dataLen];
            for(int data_n = 0; data_n < m_protocol.m_dataLen; data_n++)
            {
                m_protocol.m_data[data_n] = CirBuff::readByte();
            }
        }else
        {
            CirBuff::readByte();
        }

        if(CirBuff::readByte() == END_RESD_MSG)
        {
            if(CirBuff::readByte() == m_protocol.gainCheckSum())
            {
                return true;
            }
        }
    }
    return false;
}

void SerialThread::sendDataToSerial(const QByteArray &msg)
{
    qDebug() << "Send: " << msg.toHex();
    m_serialport->write(msg);
}

void SerialThread::slotReadyRead(void)
{
    QByteArray requestData;
    requestData = m_serialport->readAll();

    if(requestData != NULL)
    {
        qDebug() << "Recv: " << requestData.toHex();
        for(int i = 0; i < requestData.size(); i++)
        {
            CirBuff::writeByte(requestData.at(i));
        }
    }
    emit signalShowRecvData(requestData);
    requestData.clear();
}

bool SerialThread::openSerialPort(const QString &portName, int baudRate,
                                  int parity, int databits, int stopbit)
{
    m_serialport->setPortName(portName);
    m_serialport->setBaudRate(baudRate);

    switch(parity)
    {
    case 0: m_serialport->setParity(QSerialPort::NoParity);break;
    case 1: m_serialport->setParity(QSerialPort::OddParity);break;
    case 2: m_serialport->setParity(QSerialPort::EvenParity);break;
    default: break;
    }

    switch(databits)
    {
    case 0: m_serialport->setDataBits(QSerialPort::Data8);break;
    case 1: m_serialport->setDataBits(QSerialPort::Data7);break;
    case 2: m_serialport->setDataBits(QSerialPort::Data6);break;
    default: break;
    }

    switch(stopbit)
    {
    case 0: m_serialport->setStopBits(QSerialPort::OneStop);break;
    case 1: m_serialport->setStopBits(QSerialPort::TwoStop);break;
    default: break;
    }

    m_serialport->setFlowControl(QSerialPort::NoFlowControl);
    return m_serialport->open(QIODevice::ReadWrite);
}

void SerialThread::closeSerialPort(void)
{
    m_serialport->clear();
    m_serialport->close();
}

